package allod.som

import java.awt.image.BufferedImage

/**
 * Created by IntelliJ IDEA.
 * User: allod
 * Date: 13 лют 2010
 * Time: 23:04:13
 */

object UMatrixBuilder {
  val zoom = 25

  def getImage(lattice: Lattice): BufferedImage = {
    val uMatrix = createUMatrix(lattice)
    var maximum = 0d
    uMatrix.foreach(_.foreach(el => maximum = maximum max el))
    val width = lattice.columns
    val height = lattice.rows
    val image = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB)
    for{
      w <- 0 until width
      h <- 0 until height
      value: Int = ((uMatrix(w)(h) / maximum) * 255).asInstanceOf[Int]
    } image.setRGB(h, w, 0xff << 24 | value << 16 | value << 8 | value)
    val result = new BufferedImage(height * zoom, width * zoom, BufferedImage.TYPE_INT_RGB)
    result.getGraphics.drawImage(image, 0, 0, height * zoom, width * zoom, null)
    result
  }

  private def createUMatrix(lattice: Lattice): Array[Array[Double]] = {
    val matrix = new Array[Array[Double]](lattice.columns, lattice.rows)
    for (w <- 0 until lattice.columns; h <- 0 until lattice.rows)
      matrix(w)(h) = getValue(w, h, lattice)
    matrix
  }

  private def getValue(x: Int, y: Int, lattice: Lattice): Double = {
    val neuron = (x, y)
    var value = 0.0
    if (x != 0) {
      value += lattice.distanceToNeuron(neuron, (x - 1, y))
    }
    if (x != lattice.columns - 1) {
      value += lattice.distanceToNeuron(neuron, (x + 1, y))
    }
    if (y != 0) {
      value += lattice.distanceToNeuron(neuron, (x, y - 1))
    }
    if (y != lattice.rows - 1) {
      value += lattice.distanceToNeuron(neuron, (x, y + 1))
    }
    if (x != 0 && y != 0) {
      value += lattice.distanceToNeuron(neuron, (x - 1, y - 1))
    }
    if (x != lattice.columns - 1 && y != lattice.rows - 1) {
      value += lattice.distanceToNeuron(neuron, (x + 1, y + 1))
    }
    if (x != 0 && y != lattice.rows - 1) {
      value += lattice.distanceToNeuron(neuron, (x - 1, y + 1))
    }
    if (x != lattice.columns - 1 && y != 0) {
      value += lattice.distanceToNeuron(neuron, (x + 1, y - 1))
    }
    value
  }
}